package ca.etsmtl.log430.common.gestion;

/**
 * This class validate the assignment operation.
 * 
 * @author D. Quispe, ETS
 * @version 1.1, 2014-Oct-12
 */

/*
 * Modification Log
 * ************************************************************************
 * v1.1, 2014-Oct-12, D. Quispe - Compatibility with JRE 1.6 for getWorkloadFromPriority method.
 * v1.0, 2014-Sep-29, D. Quispe - Original version.
 * ************************************************************************
 */

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import ca.etsmtl.log430.common.donnees.Project;
import ca.etsmtl.log430.common.donnees.ProjectList;
import ca.etsmtl.log430.common.donnees.Resource;

public class AssignmentValidator {

	private Resource resource;
	private Project project;
	private ProjectList allProject;
	
	public AssignmentValidator(Resource resourceToAssign, Project projectForAssignment, ProjectList allProjectsAvailable) {
		this.resource = resourceToAssign;
		this.project = projectForAssignment;
		this.allProject = allProjectsAvailable;
	}
	
	/**
	 * This method validates if the assignment is possible. 
	 */
	public boolean isAssignationValid() {
		ProjectList projects = getProjectsConcerned();
		
		double maxWorkloadFound = getMaxWorkloadFound(projects);
		
		if (maxWorkloadFound + getWorkloadFromPriority(project.getPriority()) > 1) return false;
		return true;
	}
	
	public boolean isAlreadyAssigned() {
		return resource.getPreviouslyAssignedProjectList().findProject(project) ||		
		resource.getProjectsAssigned().findProject(project);
	}
	
	/**
	 * This method get projects concerned. It mean that projects date should be between start/end date of project to assign.
	 */
	private ProjectList getProjectsConcerned() {
		ProjectList projectList = new ProjectList();
		
		ProjectList tempList = resource.getPreviouslyAssignedProjectList();
		tempList.goToFrontOfList();
		
		boolean done = false;
		while (!done) {
			Project tempProject = tempList.getNextProject();
			if (tempProject == null) {
				done = true;
			} else {
				if (!projectList.findProject(tempProject) && !tempProject.getID().equals("")) {	
					tempProject = allProject.findProjectByID(tempProject.getID());
					if (isDateOverlapProject(getDate(project.getStartDate()), getDate(project.getEndDate()), tempProject)) {
						projectList.addProject(tempProject);
					}
				} // if
			} // if
		} // while
		
		tempList = resource.getProjectsAssigned();
		tempList.goToFrontOfList();
		
		done = false;
		while (!done) {
			Project tempProject = tempList.getNextProject();
			if (tempProject == null) {
				done = true;
			} else {
				if (!projectList.findProject(tempProject) && !tempProject.getID().equals("")) {
					tempProject = allProject.findProjectByID(tempProject.getID());
					if (isDateOverlapProject(getDate(project.getStartDate()), getDate(project.getEndDate()), tempProject)) {
						projectList.addProject(tempProject);
					}
				} // if
			} // if
		} // while
		
		return projectList;
	}
	
	/**
	 * This method return date type from date string.
	 */
	private Date getDate(String date){
		Date newDate = null;
		try {
			newDate = new SimpleDateFormat("yyyy-MM-dd").parse(date);
		} catch (ParseException e) {
			System.err.println("Error on convert date!");
		}
		
		return newDate;
	}
	
	/**
	 * This method return workload value of all project assigned to resource.
	 */
	private double getMaxWorkloadFound(ProjectList projectList) {
		double maxWorkload = 0.0;
		
// Algorithm to find maxworkload on overlap projects
//		for each days in project start/end date (wich one will be assignee)
//			workload = 0.0
//			for each concerned project
//				if project overlap the day
//					workload += projet.workload
//				
//			if worload > maxworkload
//				maxworkload = workload
		
	    Calendar calendar = new GregorianCalendar();
	    calendar.setTime(getDate(project.getStartDate()));

	    while (calendar.getTime().compareTo(getDate(project.getEndDate())) <= 0)
	    {
			double workload = 0.0;
			projectList.goToFrontOfList();
			boolean done = false;
			while (!done) {
				Project projectFromList = projectList.getNextProject();
				if (projectFromList == null) {
					done = true;
				} else {
					if (isDateOverlapProject(calendar.getTime(), calendar.getTime(), projectFromList)) {
						workload += getWorkloadFromPriority(projectFromList.getPriority());
					}
				} // if
			} // while
			
			if (workload > maxWorkload) maxWorkload = workload;
		 
			calendar.add(Calendar.DATE, 1);
	    } // while
		
		
		
		
		return maxWorkload;
	}
	
	/**
	 * This method return workload value of specific project priority.
	 */
	private double getWorkloadFromPriority(String priority) { 
		if (priority.equals("L")) return 0.25;
		if (priority.equals("M")) return 0.5;
		if (priority.equals("H")) return 1;
		
		return 0.0;
	}
	
	/**
	 * This method validate if the date of project which resource want to assign is between start/end date of a project in list or vice versa.
	 */
	private boolean isDateOverlapProject(Date startDate, Date endDate, Project projectFromList) {
		Date dateStartFromList = getDate(projectFromList.getStartDate());
		Date dateEndFromList = getDate(projectFromList.getEndDate());
		
		if (
			(startDate.compareTo(dateStartFromList) >= 0 && startDate.compareTo(dateEndFromList) <= 0) ||
			(endDate.compareTo(dateStartFromList) >= 0 && endDate.compareTo(dateEndFromList) <= 0) ||
			(dateStartFromList.compareTo(startDate) >= 0 && dateStartFromList.compareTo(endDate) <= 0) ||
			(dateEndFromList.compareTo(startDate) >= 0 && dateEndFromList.compareTo(endDate) <= 0)
			) {
			return true;	
		}

		return false;
	}
}
